package re_0905.question_ioc.xml;



import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import re_0905.question_ioc.MoterService;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@MoterService
public class MoterIOC {
    private String xmlPath;
    private ConcurrentHashMap<String, Object> ioc = new ConcurrentHashMap<>();

    public MoterIOC(String xmlPath) throws DocumentException, NoSuchMethodException, IllegalAccessException, InstantiationException, NoSuchFieldException, InvocationTargetException, ClassNotFoundException {
        this.xmlPath = xmlPath;
        setAllBean(getAllBean(readXml()));
    }
    public MoterIOC(){}
    public Object getBean(String classId) {
        //加入到反射
        return ioc.get(classId);
    }

    private Element readXml() throws DocumentException {
        SAXReader saxReader = new SAXReader();

        Document document = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
        return document.getRootElement();
    }

    private List<Element> getAllBean(Element rootElement) {
        List<Element> beans = rootElement.elements("bean");
        return beans;
    }

    private void setAllBean(List<Element> beans) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        for (Element bean : beans) {
            //通过午餐对象获取对象实例
            Class<?> aClass = Class.forName(bean.attribute("class").getValue());

            Constructor<?> constructor = aClass.getDeclaredConstructor(null);
            constructor.setAccessible(true);
            Object o = constructor.newInstance(null);

            //设置成员属性
            setProperties(bean, aClass, o);
            ioc.put(bean.attribute("id").getValue(), o);
        }
    }

    private void setProperties(Element bean, Class<?> aClass, Object o) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        List<Element> properties = bean.elements("property");
        for (Element property : properties) {
            Field name = aClass.getDeclaredField(property.attribute("name").getValue());
            name.setAccessible(true);
            Class<?> type = name.getType();
            if (type == Integer.class)
                name.set(o, Integer.parseInt(property.attribute("value").getValue()));
            else name.set(o, property.attribute("value").getValue());
//            Method name1 = aClass.getDeclaredMethod(getMethodName(property.attribute("name").getValue()), name.getType());
//            name1.setAccessible(true);
//            System.out.println((Student)o);
//            name1.invoke(o,property.attribute("value").getValue());
        }
    }

    public String getMethodName(String field) {
        return "set" + field.substring(0, 1).toUpperCase() + field.substring(1, field.length());
    }



    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, ClassNotFoundException, DocumentException, InvocationTargetException, NoSuchFieldException {
        MoterIOC moterIOC = new MoterIOC("spring.xml");
        Student student = (Student) moterIOC.getBean("student");
        Student student1 = (Student) moterIOC.getBean("student");
        System.out.println(student);
        student.setAge("33");
        System.out.println(student1);
        System.out.println(student1 == student);
        System.out.println();
    }
}
